package aos.framework.core.redis;

import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.stereotype.Service;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * <b>Redis客户端</b>
 *
 * @author xiongchun
 */
@Service
public class RedisCacheService {

    private JedisPool jedisPool;
    private Logger logger = LogManager.getLogger(RedisCacheService.class);

    /**
     * 获取字符串型数据
     *
     * @param key
     * @return
     */
    public String get(String key) {
        return get(key, null);
    }

    /**
     * 根据key获取相应字符串数据
     *
     * @param key
     * @param defa 默认值
     * @return 未找到缓存则返回默认值
     */
    public String get(String key, String defa) {
        Jedis jedis = getJedis();
        try {
            return StringUtils.isNotEmpty(jedis.get(key)) ? jedis.get(key) : defa;
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return defa;
    }

    /**
     * 删除字符串数据
     *
     * @param key
     */
    public void del(String key) {
        Jedis jedis = getJedis();
        try {
            jedis.del(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
    }

    private Jedis getJedis() {
        return JedisUtil.getJedisClient();
    }

    /**
     * 设置字符串型数据
     *
     * @param key     存储键
     * @param value   存储值
     * @param timeout 超时时间(单位：秒） 设置为0，则无时效性。
     * @return
     */
    public void set(String key, String value, int timeout) {
        set(key, value);
        if (timeout > 0) {
            expire(key, timeout);
        }
    }

    public void set(String key, String value) {
        Jedis jedis = getJedis();
        try {
            jedis.set(key, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
    }

    /**
     * 设置字符串型数据过期时间
     *
     * @param key     存储键
     * @param timeout 超时时间(单位：秒）
     * @param key
     */
    public void expire(String key, int timeout) {
        Jedis jedis = getJedis();
        try {
            jedis.expire(key, timeout);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
    }

    public Long incr(String key) {
        return incr(key, null);
    }

    public Long incr(String key, Long defa) {
        Jedis jedis = getJedis();
        try {
            Long incr = jedis.incr(key);
            return incr != null ? incr : defa;
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return defa;
    }

    public boolean sIsMember(String key, String value) {
        Jedis jedis = getJedis();
        try {
            return jedis.sismember(key, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return false;
    }

    public Long sAdd(String key, String value) {
        Jedis jedis = getJedis();
        try {
            return jedis.sadd(key, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public String hMSet(String key, Map<String, String> cacheMap) {
        Jedis jedis = getJedis();
        try {
            return jedis.hmset(key, cacheMap);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return "Exception";
    }

    public void hMSet(String key, Map<String, String> cacheMap, int timeout) {
        hMSet(key, cacheMap);
        if (timeout > 0) {
            expire(key, timeout);
        }
    }

    public Long lPush(String key, String value) {
        Jedis jedis = getJedis();
        try {
            return jedis.lpush(key, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public Long lRem(String key, long count, String value) {
        Jedis jedis = getJedis();
        try {
            return jedis.lrem(key, count, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public List<String> lRange(String key, long start, long end) {
        Jedis jedis = getJedis();
        try {
            return jedis.lrange(key, start, end);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public Long lLen(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.llen(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public Set<String> keys(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.keys(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public Long hSet(String key, String field, String value) {
        Jedis jedis = getJedis();
        try {
            return jedis.hset(key, field, value);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public void hSet(String key, String field, String value, int timeout) {
        hSet(key, field, value);
        if (timeout > 0) {
            expire(key, timeout);
        }
    }

    public Long hDel(String key, String... field) {
        Jedis jedis = getJedis();
        try {
            return jedis.hdel(key, field);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public String hGet(String key, String field) {
        return hGet(key, field, null);
    }

    public String hGet(String key, String field, String defa) {
        Jedis jedis = getJedis();
        try {
            return StringUtils.isNotEmpty(jedis.hget(key, field)) ? jedis.hget(key, field) : defa;
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return defa;
    }

    public List<String> hvals(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.hvals(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public String type(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.type(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public Long ttl(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.ttl(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public Set<String> hKeys(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.hkeys(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public List<String> sRandMember(String key, int count) {
        Jedis jedis = getJedis();
        try {
            return jedis.srandmember(key, count);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

    public Long sCard(String key) {
        Jedis jedis = getJedis();
        try {
            return jedis.scard(key);
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return Long.valueOf("0");
    }

    public void flushAll() {
        Jedis jedis = getJedis();
        try {
            jedis.flushAll();
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
    }

    public String info() {
        Jedis jedis = getJedis();
        try {
            return jedis.info();
        } catch (Exception e) {
            logger.error(e);
        } finally {
            jedis.close();
        }
        return null;
    }

}
